#ifndef LEAMDATAOUTSTREAMHH
#define LEAMDATAOUTSTREAMHH
#include "leam-typedefs.hh"
#include "leam-out-stream.hh"
#include "leam-messages.hh"
#include "leam-errors.hh"

namespace leam
{
    //This is created by the leam stream and returned with the application
    //requests to write a certain number of bytes.
    class LeamDataOutStream : public licada::IBinaryOutStream
    {
	TLength length;
	ILeamOutStream* stream;
	LeamDataOutStream( const LeamDataOutStream& other );
	LeamDataOutStream& operator=( const LeamDataOutStream& other );
    public:
	LeamDataOutStream()
	    : length(0), stream( NULL ) {}
	void setup( TLength len, ILeamOutStream* _stream ) {
	    length = len;
	    stream = _stream;
	}
	~LeamDataOutStream(){}
	TLength getRemaining() { return length; }
	void operator<< ( const licada::TDataVector& data ) {
	    TLength len = (TLength)data.size();
	    checkLength( len );
	    *stream << data;
	    checkFinish(len);
	}
	void operator<< ( licada::uint8 byte ) {
	    checkLength( 1 );
	    *stream << byte;
	    checkFinish(1);
	}

    private:
	void checkLength( TLength request ) {
	    if ( request > length )
		throw LeamDataStreamOverWrite( length, request );
	}
	void checkFinish( TLength len ) {
	    length -= std::min( len, length);
	    if ( length == 0 )
		stream->flush(); //Ensure final message is sent
	}
	
    };
}
#endif
